About Issues Tutorials Documentation
</span>
This notebook builds a small DNA double helix, assigns a forcefield to it, and runs a molecular dynamics simulation.
In [ ]:
import moldesign as mdt
from moldesign import units as u
%matplotlib inline
from matplotlib.pyplot import *
# seaborn is optional -- it makes plots nicer
try: import seaborn
except ImportError: pass
In [ ]:
dna_structure = mdt.build_dna_helix('ACTGACTG', helix_type='b')
dna_structure.draw()
In [ ]:
dna_structure
The cell below adds forcefield parameters to the molecule.
NOTE: This molecule because is not missing expected atoms. If your molecule is missing atoms (e.g., it's missing its hydrogens), use the Forcefield.create_prepped_molecule
method instead of Forcefield.assign
.
Click on the ERRORS/WARNING tab to see any warnings raised during assignment.
In [ ]:
ff = mdt.forcefields.DefaultAmber()
ff.assign(dna_structure)
In [ ]:
rs = mdt.widgets.ResidueSelector(dna_structure)
rs
In [ ]:
if len(rs.selected_residues) == 0:
raise ValueError("You didn't click on anything!")
rs.selected_residues
In [ ]:
for residue in rs.selected_residues:
print('Constraining position for residue %s' % residue)
for atom in residue.atoms:
dna_structure.constrain_atom(atom)
Of course, fixing the positions of the terminal base pairs is a fairly extreme step. For extra credit, see if you can find a less heavy-handed keep the terminal base pairs bonded. (Try using tab-completion to see what other constraint methods are available)
In [ ]:
dna_structure.set_energy_model(mdt.models.OpenMMPotential,
implicit_solvent='obc')
dna_structure.set_integrator(mdt.integrators.OpenMMLangevin,
timestep=2.0*u.fs,
temperature=300.0*u.kelvin,
frame_interval=1.0*u.ps)
You can interactively configure these methods:
In [ ]:
dna_structure.configure_methods()
In [ ]:
trajectory = dna_structure.minimize(nsteps=200)
trajectory.draw()
In [ ]:
plot(trajectory.potential_energy)
xlabel('steps');ylabel('energy / %s' % trajectory.unit_system.energy)
title('Energy relaxation'); grid('on')
In [ ]:
traj = dna_structure.run(run_for=25.0*u.ps)
traj.draw()
In [ ]:
plot(traj.time, traj.kinetic_energy, label='kinetic energy')
plot(traj.time, traj.potential_energy - traj.potential_energy[0], label='potential_energy')
xlabel('time / {time.units}'.format(time=traj.time))
ylabel('energy / {energy.units}'.format(energy=traj.kinetic_energy))
title('Energy vs. time'); legend(); grid('on')
In [ ]:
# Using the trajectory's 'plot' method will autogenerate axes labels with the appropriate units
traj.plot('time','kinetic_temperature')
title('Temperature'); grid('on')
This cell sets up an widget that plots the RMSDs of any selected group of atoms. Select a group of atoms, then click "Run plot_rmsd" to generate a plot
In [ ]:
from ipywidgets import interact_manual
from IPython.display import display
rs = mdt.widgets.ResidueSelector(dna_structure)
def plot_rmsd():
plot(traj.time, traj.rmsd(rs.selected_atoms))
xlabel('time / fs'); ylabel(u'RMSD / Å')
interact_manual(plot_rmsd, description='plot rmsd')
rs
In [ ]: